/**
 * @file test_filelist_features.cpp
 * @brief 文件列表功能全面测试用例
 * 测试各种文件列表场景、嵌套结构和错误处理
 */

#include "../moparse.h"
#include <iostream>
#include <fstream>
#include <cassert>
#include <functional>
#include <cstdio>

class FilelistTestRunner {
public:
    FilelistTestRunner() : tests_passed_(0), tests_failed_(0) {}
    
    void run_test(const std::string& test_name, std::function<bool()> test_func) {
        std::cout << "运行文件列表测试: " << test_name << " ... ";
        try {
            if (test_func()) {
                std::cout << "通过" << std::endl;
                tests_passed_++;
            } else {
                std::cout << "失败" << std::endl;
                tests_failed_++;
            }
        } catch (const std::exception& e) {
            std::cout << "异常: " << e.what() << std::endl;
            tests_failed_++;
        }
    }
    
    void print_summary() {
        std::cout << "\n文件列表测试总结:" << std::endl;
        std::cout << "通过: " << tests_passed_ << std::endl;
        std::cout << "失败: " << tests_failed_ << std::endl;
        std::cout << "总计: " << (tests_passed_ + tests_failed_) << std::endl;
    }
    
    int get_failed_count() const { return tests_failed_; }

private:
    int tests_passed_;
    int tests_failed_;
};

// 创建文件列表测试用的模块文件
void create_filelist_test_files() {
    
    // 创建多个测试模块文件
    std::ofstream module1("filelist_module1.v");
    module1 << R"(
module module1 (
    input clk,
    input reset,
    output [7:0] data
);

parameter WIDTH = 8;

endmodule
)";
    module1.close();

    std::ofstream module2("filelist_module2.v");
    module2 << R"(
module module2 (
    input clk,
    input [7:0] data_in,
    output [7:0] data_out
);

parameter DELAY = 2;

endmodule
)";
    module2.close();

    std::ofstream module3("filelist_module3.v");
    module3 << R"(
module module3 (
    input enable,
    output ready
);

endmodule
)";
    module3.close();

    std::ofstream module4("filelist_module4.v");
    module4 << R"(
module module4 #(
    parameter SIZE = 16
) (
    input [SIZE-1:0] input_bus,
    output [SIZE-1:0] output_bus
);

endmodule
)";
    module4.close();

    // 在子目录中创建模块
    system("mkdir -p subdir1 subdir2");
    
    std::ofstream sub1("subdir1/sub_module1.v");
    sub1 << R"(
module sub_module1 (
    input clk,
    output data
);
endmodule
)";
    sub1.close();

    std::ofstream sub2("subdir2/sub_module2.v");
    sub2 << R"(
module sub_module2 (
    input clk,
    output data
);
endmodule
)";
    sub2.close();
}

// 创建各种文件列表测试文件
void create_filelist_files() {
    
    // 1. 基本文件列表
    std::ofstream basic_list("basic.list");
    basic_list << "# 基本文件列表\n";
    basic_list << "filelist_module1.v\n";
    basic_list << "filelist_module2.v\n";
    basic_list << "filelist_module3.v\n";
    basic_list.close();

    // 2. 包含注释和空行的文件列表
    std::ofstream comment_list("comment.list");
    comment_list << "# 包含注释的文件列表\n";
    comment_list << "\n";  // 空行
    comment_list << "filelist_module1.v  # 第一个模块\n";
    comment_list << "\n";  // 另一个空行
    comment_list << "// C风格注释\n";
    comment_list << "filelist_module2.v\n";
    comment_list << "# 另一个注释\n";
    comment_list << "filelist_module3.v\n";
    comment_list.close();

    // 3. 带路径的文件列表
    std::ofstream path_list("path.list");
    path_list << "# 带路径的文件列表\n";
    path_list << "filelist_module1.v\n";
    path_list << "subdir1/sub_module1.v\n";
    path_list << "subdir2/sub_module2.v\n";
    path_list.close();

    // 4. 单层嵌套文件列表
    std::ofstream main_list("main.list");
    main_list << "# 主文件列表\n";
    main_list << "filelist_module1.v\n";
    main_list << "-f sub.list\n";
    main_list << "filelist_module4.v\n";
    main_list.close();

    std::ofstream sub_list("sub.list");
    sub_list << "# 子文件列表\n";
    sub_list << "filelist_module2.v\n";
    sub_list << "filelist_module3.v\n";
    sub_list.close();

    // 5. 多层嵌套文件列表
    std::ofstream deep_main("deep_main.list");
    deep_main << "# 深层嵌套主文件\n";
    deep_main << "filelist_module1.v\n";
    deep_main << "-f deep_level1.list\n";
    deep_main.close();

    std::ofstream deep_level1("deep_level1.list");
    deep_level1 << "# 第一层嵌套\n";
    deep_level1 << "filelist_module2.v\n";
    deep_level1 << "-f deep_level2.list\n";
    deep_level1.close();

    std::ofstream deep_level2("deep_level2.list");
    deep_level2 << "# 第二层嵌套\n";
    deep_level2 << "filelist_module3.v\n";
    deep_level2 << "-f deep_level3.list\n";
    deep_level2.close();

    std::ofstream deep_level3("deep_level3.list");
    deep_level3 << "# 第三层嵌套\n";
    deep_level3 << "filelist_module4.v\n";
    deep_level3.close();

    // 6. 复杂嵌套结构
    std::ofstream complex_main("complex_main.list");
    complex_main << "# 复杂嵌套结构\n";
    complex_main << "filelist_module1.v\n";
    complex_main << "-f complex_branch1.list\n";
    complex_main << "filelist_module2.v\n";
    complex_main << "-f complex_branch2.list\n";
    complex_main.close();

    std::ofstream complex_branch1("complex_branch1.list");
    complex_branch1 << "# 分支1\n";
    complex_branch1 << "filelist_module3.v\n";
    complex_branch1 << "-f complex_leaf1.list\n";
    complex_branch1.close();

    std::ofstream complex_branch2("complex_branch2.list");
    complex_branch2 << "# 分支2\n";
    complex_branch2 << "filelist_module4.v\n";
    complex_branch2 << "-f complex_leaf2.list\n";
    complex_branch2.close();

    std::ofstream complex_leaf1("complex_leaf1.list");
    complex_leaf1 << "# 叶子节点1\n";
    complex_leaf1 << "subdir1/sub_module1.v\n";
    complex_leaf1.close();

    std::ofstream complex_leaf2("complex_leaf2.list");
    complex_leaf2 << "# 叶子节点2\n";
    complex_leaf2 << "subdir2/sub_module2.v\n";
    complex_leaf2.close();

    // 7. 循环引用测试
    std::ofstream circular1("circular1.list");
    circular1 << "# 循环引用1\n";
    circular1 << "filelist_module1.v\n";
    circular1 << "-f circular2.list\n";
    circular1.close();

    std::ofstream circular2("circular2.list");
    circular2 << "# 循环引用2\n";
    circular2 << "filelist_module2.v\n";
    circular2 << "-f circular3.list\n";
    circular2.close();

    std::ofstream circular3("circular3.list");
    circular3 << "# 循环引用3\n";
    circular3 << "filelist_module3.v\n";
    circular3 << "-f circular1.list\n";  // 回到circular1，形成循环
    circular3.close();

    // 8. 错误测试文件列表
    std::ofstream error_list("error.list");
    error_list << "# 包含错误的文件列表\n";
    error_list << "filelist_module1.v\n";
    error_list << "nonexistent_file.v\n";  // 不存在的文件
    error_list << "filelist_module2.v\n";
    error_list.close();

    // 9. 包含不存在嵌套文件的列表
    std::ofstream missing_nested("missing_nested.list");
    missing_nested << "# 包含不存在嵌套文件\n";
    missing_nested << "filelist_module1.v\n";
    missing_nested << "-f nonexistent.list\n";  // 不存在的文件列表
    missing_nested << "filelist_module2.v\n";
    missing_nested.close();

    // 10. 带引号的文件路径
    std::ofstream quoted_list("quoted.list");
    quoted_list << "# 带引号的文件路径\n";
    quoted_list << "\"filelist_module1.v\"\n";
    quoted_list << "-f \"sub.list\"\n";
    quoted_list << "'filelist_module3.v'\n";  // 单引号（可能不支持）
    quoted_list.close();

    // 11. 超大文件列表
    std::ofstream large_list("large.list");
    large_list << "# 超大文件列表\n";
    for (int i = 0; i < 1000; i++) {
        large_list << "filelist_module" << (i % 4 + 1) << ".v\n";
    }
    large_list.close();

    // 12. 空文件列表
    std::ofstream empty_list("empty.list");
    empty_list << "# 空文件列表\n";
    empty_list << "# 只有注释，没有实际文件\n";
    empty_list.close();
}

// 清理文件列表测试文件
void cleanup_filelist_test_files() {
    std::vector<std::string> files = {
        "filelist_module1.v", "filelist_module2.v", "filelist_module3.v", "filelist_module4.v",
        "basic.list", "comment.list", "path.list", "main.list", "sub.list",
        "deep_main.list", "deep_level1.list", "deep_level2.list", "deep_level3.list",
        "complex_main.list", "complex_branch1.list", "complex_branch2.list", 
        "complex_leaf1.list", "complex_leaf2.list",
        "circular1.list", "circular2.list", "circular3.list",
        "error.list", "missing_nested.list", "quoted.list", "large.list", "empty.list",
        "basic_output.modb", "comment_output.modb", "path_output.modb", 
        "main_output.modb", "deep_output.modb", "complex_output.modb", "large_output.modb"
    };
    
    // 清理子目录文件
    system("rm -rf subdir1 subdir2");
    
    for (const auto& file : files) {
        std::remove(file.c_str());
    }
}

// 测试基本文件列表解析
bool test_basic_filelist() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFileList("basic.list")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    if (db.modules_size() != 3) {
        return false;
    }
    
    // 检查是否解析出了正确的模块
    std::vector<std::string> expected_modules = {"module1", "module2", "module3"};
    std::vector<std::string> found_modules;
    
    for (const auto& module : db.modules()) {
        found_modules.push_back(module.name());
    }
    
    for (const auto& expected : expected_modules) {
        bool found = false;
        for (const auto& actual : found_modules) {
            if (actual == expected) {
                found = true;
                break;
            }
        }
        if (!found) {
            return false;
        }
    }
    
    return parser.saveToModb("basic_output.modb");
}

// 测试包含注释和空行的文件列表
bool test_comment_filelist() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFileList("comment.list")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    return db.modules_size() == 3 && parser.saveToModb("comment_output.modb");
}

// 测试带路径的文件列表
bool test_path_filelist() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFileList("path.list")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    // 应该解析出3个模块：main模块 + 2个子目录模块
    return db.modules_size() == 3 && parser.saveToModb("path_output.modb");
}

// 测试单层嵌套文件列表
bool test_single_nested_filelist() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFileList("main.list")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    // 应该解析出4个模块
    return db.modules_size() == 4 && parser.saveToModb("main_output.modb");
}

// 测试深层嵌套文件列表
bool test_deep_nested_filelist() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFileList("deep_main.list")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    // 应该解析出4个模块（通过3层嵌套）
    return db.modules_size() == 4 && parser.saveToModb("deep_output.modb");
}

// 测试复杂嵌套结构
bool test_complex_nested_filelist() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFileList("complex_main.list")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    // 应该解析出6个模块
    return db.modules_size() == 6 && parser.saveToModb("complex_output.modb");
}

// 测试循环引用检测
bool test_circular_reference_detection() {
    VerilogParser parser;
    
    // 应该能够检测循环引用并成功处理（不进入死循环）
    bool result = parser.parseVerilogFileList("circular1.list");
    
    // 不管是否成功解析，重要的是程序不会死循环
    return true;
}

// 测试错误文件处理
bool test_error_file_handling() {
    VerilogParser parser;
    
    // 包含不存在文件的列表，应该能够处理错误并继续
    bool result = parser.parseVerilogFileList("error.list");
    
    // 可能会失败，但不应该崩溃
    if (result) {
        const auto& db = parser.getDatabase();
        // 至少应该解析出存在的文件
        return db.modules_size() >= 2;
    }
    
    return true; // 失败也是可以接受的
}

// 测试不存在的嵌套文件
bool test_missing_nested_file() {
    VerilogParser parser;
    
    // 包含不存在嵌套文件的列表
    bool result = parser.parseVerilogFileList("missing_nested.list");
    
    // 应该能够处理错误并继续解析其他文件
    return true; // 不崩溃就算成功
}

// 测试带引号的文件路径
bool test_quoted_file_paths() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFileList("quoted.list")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    // 至少应该解析出一些模块
    return db.modules_size() >= 2;
}

// 测试超大文件列表
bool test_large_filelist() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFileList("large.list")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    // 应该只有4个唯一模块（因为文件重复）
    return db.modules_size() == 4 && parser.saveToModb("large_output.modb");
}

// 测试空文件列表
bool test_empty_filelist() {
    VerilogParser parser;
    
    // 空文件列表应该能够处理
    bool result = parser.parseVerilogFileList("empty.list");
    
    if (result) {
        const auto& db = parser.getDatabase();
        return db.modules_size() == 0;
    }
    
    return true; // 失败也可以接受
}

// 测试不存在的文件列表
bool test_nonexistent_filelist() {
    VerilogParser parser;
    
    // 不存在的文件列表应该返回false
    return !parser.parseVerilogFileList("nonexistent.list");
}

// 测试文件列表与单文件解析的一致性
bool test_filelist_consistency() {
    VerilogParser parser1, parser2;
    
    // 使用文件列表解析
    if (!parser1.parseVerilogFileList("basic.list")) {
        return false;
    }
    
    // 逐个解析文件
    if (!parser2.parseVerilogFile("filelist_module1.v")) {
        return false;
    }
    if (!parser2.parseVerilogFile("filelist_module2.v")) {
        return false;
    }
    if (!parser2.parseVerilogFile("filelist_module3.v")) {
        return false;
    }
    
    const auto& db1 = parser1.getDatabase();
    const auto& db2 = parser2.getDatabase();
    
    // 模块数量应该相同
    return db1.modules_size() == db2.modules_size();
}

// 测试嵌套深度限制
bool test_nesting_depth_limit() {
    // 创建极深的嵌套结构
    const int max_depth = 50;
    
    for (int i = 0; i < max_depth; i++) {
        std::string filename = "depth_" + std::to_string(i) + ".list";
        std::ofstream file(filename);
        
        if (i == 0) {
            file << "filelist_module1.v\n";
        }
        
        if (i < max_depth - 1) {
            file << "-f depth_" << (i + 1) << ".list\n";
        } else {
            file << "filelist_module2.v\n";
        }
        file.close();
    }
    
    VerilogParser parser;
    bool result = parser.parseVerilogFileList("depth_0.list");
    
    // 清理深度测试文件
    for (int i = 0; i < max_depth; i++) {
        std::string filename = "depth_" + std::to_string(i) + ".list";
        std::remove(filename.c_str());
    }
    
    // 能够处理深层嵌套或者合理地拒绝
    return true;
}

int main() {
    std::cout << "开始文件列表功能全面测试...\n" << std::endl;
    
    // 创建测试文件
    create_filelist_test_files();
    create_filelist_files();
    
    FilelistTestRunner runner;
    
    // 运行文件列表测试
    runner.run_test("基本文件列表", test_basic_filelist);
    runner.run_test("注释文件列表", test_comment_filelist);
    runner.run_test("路径文件列表", test_path_filelist);
    runner.run_test("单层嵌套", test_single_nested_filelist);
    runner.run_test("深层嵌套", test_deep_nested_filelist);
    runner.run_test("复杂嵌套结构", test_complex_nested_filelist);
    runner.run_test("循环引用检测", test_circular_reference_detection);
    runner.run_test("错误文件处理", test_error_file_handling);
    runner.run_test("缺失嵌套文件", test_missing_nested_file);
    runner.run_test("引号文件路径", test_quoted_file_paths);
    runner.run_test("超大文件列表", test_large_filelist);
    runner.run_test("空文件列表", test_empty_filelist);
    runner.run_test("不存在文件列表", test_nonexistent_filelist);
    runner.run_test("解析一致性", test_filelist_consistency);
    runner.run_test("嵌套深度限制", test_nesting_depth_limit);
    
    // 清理测试文件
    cleanup_filelist_test_files();
    
    // 输出测试结果
    runner.print_summary();
    
    return runner.get_failed_count() > 0 ? 1 : 0;
}